package com.blogspot.sunserenity.binarytools;

import java.util.ArrayList;

public class BinaryTools {
	
	public static final int DefaultCharCodeLen = 8; 
	
	public static byte[] unicodeToBite (ArrayList<Integer> msg, int ccl) {
		byte[] btMsg = new byte[msg.size() * ccl];
		int indx = 0;
		for (int ii : msg) {
			for (int i = 0; i < ccl; i++)
				btMsg[indx + (ccl-1)-i] = (byte)((ii >> i) & 1);
			indx += ccl;
		}
		return btMsg;
	}
	public static byte[] unicodeStringToBite (String msg, int ccl) {
		ArrayList<Integer> ucMsg = new ArrayList<Integer>();
		for (char ch : msg.toCharArray()) {
			ucMsg.add((int)ch);
		}
		return unicodeToBite (ucMsg, ccl);
	}
	public static ArrayList<Integer> biteToUnicode (byte[] btMsg, int ccl) {
		ArrayList<Integer> ucMsg = new ArrayList<Integer>();
		int buf = btMsg[0];
		for (int ii = 1; ii < btMsg.length; ii++)
			if ((ii % ccl) == 0) {
				ucMsg.add(buf);
				buf = btMsg[ii];
			} else 
				buf = (buf << 1) | btMsg[ii];
		ucMsg.add(buf);
		return ucMsg;
	}	
	public static boolean isSame (byte[] v1, byte[] v2) {
		boolean rc = true;
		if (v1.length == v2.length) {
			for (int i = 0; i < v1.length && rc; i++) {
				rc = (v1[i] == v2[i]);
			}
		} else {
			rc = false;
		}
		return rc;
	}
	public static byte[] add2(byte[] aV, byte[] bV) {
		byte[] outMsg = new byte[bV.length];
		for (int indx = 0; indx < outMsg.length; indx++)
			outMsg[indx] = (byte)(aV[indx] ^ bV[indx]);
		return outMsg;
	}
	public static String makeStringFromBinary (String prefix, byte[] arr) {
		StringBuilder sb = new StringBuilder(prefix);
		for (byte b : arr)
			sb.append(b);
		return sb.toString();
	}
	public static String unicodeCPtoString (ArrayList<Integer> ucMsg) {
		StringBuilder sb = new StringBuilder();
		for (int ucCP: ucMsg)
			sb.append(Character.toChars(ucCP));
		return sb.toString();
	}
	
	public static byte[] shiftLeft (byte[] src, int offset) {
		byte[] rb = new byte[src.length + offset];
		int i=0;
		for (byte b : src) {
			rb[i++] = b;
		}
		return rb;
	}
	public static byte[] shiftRight (byte[] src, int offset) {
		byte[] rb = new byte[src.length - offset];
		int i = 0;
		for (byte b : src) {
			if (i < rb.length)
				rb[i++] = b;
			else break;
		}
		return rb;
	}

	public static byte[] expand (byte[] src, int offset) {
		byte[] rb = new byte[src.length + offset];
		int i = offset;
		for (byte b : src) {
			rb[i++] = b;
		}
		return rb;
	}
	public static byte[] trim (byte[] src) {
		int offset = 0;
		for (byte b : src)
			if (b != 1) offset++;
			else break;
		byte[] rb = new byte[src.length - offset];
		for (int i=0; i < rb.length; i++)
			rb[i] = src[offset + i];
		return rb;
	}
	
	public static int getInteger (byte ... bytes) {
		int result = 0;
		for (int i=bytes.length; i>0; i--) {
			result = bytes[bytes.length-i] << (i-1); 
		}
		return result;
	}
	public static byte[] getByteArrayFromInt (int number, int rank) {
		byte[] result = new byte[rank];
		for (int i=1; i<=rank; i++) {
			result[rank-i] = (byte)((number >> (i-1)) & 1);
		}
		return result;
	}
	public static byte[] circleLeftShift(byte[] bytes, int shift)  {
		byte[] result = new byte[bytes.length];
		System.arraycopy(bytes, shift, result, 0, bytes.length-shift);
		System.arraycopy(bytes, 0, result, bytes.length-shift, shift);
		return result;
	}
}